package com.pointstar.dp.software;

import java.util.Optional;

/**
 * 16年：矩阵运算：加法、乘法、转置
 *
 * @author 朱科睿
 */
public class MyMatrix {

    private Integer row;

    private Integer col;

    private Integer size;

    private double[][] data;

    public MyMatrix() {

    }

    public MyMatrix(double[][] matrix) {
        this.row = matrix.length;
        this.col = matrix.length > 0 ? matrix[0].length : 0;
        this.size = this.row * this.col;
        this.data = new double[row][col];
        for (int i = 0; i < this.row; i++) {
            this.data[i] = matrix[i].clone();
        }
    }

    public MyMatrix plus(MyMatrix matrix) {

        if (row.equals(matrix.row) && col.equals(matrix.col)) {
            MyMatrix result = new MyMatrix();
            result.row = row;
            result.col = col;
            result.size = result.row * result.col;
            result.data = new double[row][col];
            for (int i = 0; i < row; i++) {
                for (int j = 0; j < col; j++) {
                    result.data[i][j] = data[i][j] + matrix.data[i][j];
                }
            }
            return result;
        } else {
            return null;
        }
    }

    public MyMatrix multiply(MyMatrix matrix) {

        if (col.equals(matrix.row)) {
            MyMatrix result = new MyMatrix();
            result.row = row;
            result.col = matrix.col;
            result.size = result.row * result.col;
            result.data = new double[result.row][result.col];
            for (int i = 0; i < result.row; i++) {
                for (int j = 0; j < result.col; j++) {
                    for (int k = 0; k < col; k++) {
                        result.data[i][j] += data[i][k] * matrix.data[k][j];
                    }
                }
            }
            return result;
        } else {
            return null;
        }
    }

    public MyMatrix transpose() {

        MyMatrix result = new MyMatrix();
        result.row = row;
        result.col = col;
        result.size = result.row * result.col;
        result.data = new double[row][col];
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                result.data[j][i] = data[i][j];
            }
        }
        return result;
    }

    public void print(int width, int d) {
        System.out.println();
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                //打印字符，格式：占5列宽，小数点保留2位。
                System.out.format(String.format("%%-%d.%df", width, d), data[i][j]);
            }
            System.out.println();
        }
        System.out.println();
    }

    public static void main(String[] args) {

        double[][] a = {{2,5},{1,6}};
        double[][] b = {{1,2},{1,2}};
        MyMatrix matrixA = new MyMatrix(a);
        MyMatrix matrixB = new MyMatrix(b);
        System.out.println("matrixA:");
        matrixA.print(5, 2);
        System.out.println("matrixB:");
        matrixB.print(5,2);
        System.out.println("matrixA + matrixB:");
        Optional.ofNullable(matrixA.plus(matrixB)).ifPresent(matrix -> matrix.print(5,2));
        System.out.println("matrixA * matrixB:");
        Optional.ofNullable(matrixA.multiply(matrixB)).ifPresent(matrix -> matrix.print(5, 2));
        System.out.println("matrixA T:");
        matrixA.transpose().print(5,2);
    }
}
